/*
 * Copyright (C) 2015 yixun All Rights Reserved.
 * 
 * AreaServiceImpl.java
 */
package com.yixun.qfbao.api.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.yixun.qfbao.api.service.JobService;
import com.yixun.qfbao.api.service.ReportCommonService;
import com.yixun.qfbao.api.service.V10BindService;
import com.yixun.qfbao.apidto.SyncFollowAndAffixReqDto;
import com.yixun.qfbao.apidto.V10IntentionFollowDto;
import com.yixun.qfbao.apidto.v10dto.UpdateFirsthandIntentionAuditStatusReqDto;
import com.yixun.qfbao.dao.ApiFailLogDao;
import com.yixun.qfbao.model.ApiFailLog;
import com.yixun.qfbao.model.ReportExternal;
import com.yixun.qfbao.model.dto.ReportExternalDto;
import com.yixun.qfbao.model.enums.DelFlagEnum;
import com.yixun.qfbao.model.enums.FollowTypeEnum;
import com.yixun.qfbao.model.enums.OperationTypeEnum;
import com.yixun.qfbao.model.enums.TimeUnitTypeEnum;
import com.yixun.qfbao.service.ReportExternalService;
import com.yixun.qfbao.util.DateStyle;
import com.yixun.qfbao.util.DateUtils;
import com.yixun.qfbao.xf.model.CustomerPremises;
import com.yixun.qfbao.xf.model.FollowUpList;
import com.yixun.qfbao.xf.model.Premises;
import com.yixun.qfbao.xf.model.dto.CustomerPremisesDto;
import com.yixun.qfbao.xf.model.dto.FollowUpListDto;
import com.yixun.qfbao.xf.model.dto.PremisesDto;
import com.yixun.qfbao.xf.model.enums.*;
import com.yixun.qfbao.xf.service.CustomerPremisesService;
import com.yixun.qfbao.xf.service.FollowUpListService;
import com.yixun.qfbao.xf.service.PremisesService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.time.Instant;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class JobServiceImpl implements JobService {

	private Logger logger = LoggerFactory.getLogger(JobServiceImpl.class);

	@Autowired
	private V10BindService v10BindService;
	@Autowired
	private PremisesService premisesService;
	@Autowired
	private CustomerPremisesService customerPremisesService;
	@Autowired
	private FollowUpListService followUpListService;
	@Autowired
	private ReportExternalService reportExternalService;
	@Autowired
	private ApiFailLogDao apiFailLogDao;
	@Autowired
	private ReportCommonService reportCommonService;

	@Override
	public int flowConfirm() {
		int result = 0;
		try {
			int pageSize = 300;
			int total = 0;
			// 查询报备表中所有报备有效的记录(已到访且未签约或交易失败的数据)
			CustomerPremisesDto dto = new CustomerPremisesDto();
			//新版需求开启此job，为了不影响之前的数据，只取发版后的数据
			String dateString = "2019-05-17 00:00:00";
			Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(dateString);
			dto.setCreateTimeBefore(date);
			dto.setCustomerStatus(CustomerStatusEnum.has_visited.getNo());
			dto.setSql(" confirm_status != 3 and confirm_status != 4 ");
			total = customerPremisesService.overTradeTimeCount(dto);
			for (int i = 0; i < (total + pageSize - 1) / 300; i++) {
				List<CustomerPremises> lists = customerPremisesService.selectMyListByDto(dto, pageSize * i, pageSize);
				for (CustomerPremises cus : lists) {
					// 导入报备不参与自动无效
					if (ReportTypeEnum.type_3.getNo().equals(cus.getReportType())) {
						continue;
					}
					FollowUpListDto entity = new FollowUpListDto();
					/**
					 * 复访顺延交易延长时间 V1.5.3(恒信需求)
					 * sangtao
					 */
					Premises premises = premisesService.selectSimpleById(cus.getPremisesId());
					if (null == premises) {
						continue;
					}
					if (premises.getSaveDaysType() == null || TimeUnitTypeEnum.NONE.getNo().equals(String.valueOf(premises.getSaveDaysType()))) {
						continue;
					}
					if (CustomerStatusEnum.has_visited.getNo().equals(cus.getCustomerStatus()) && ConfirmStatusEnum.confirm.getNo().equals(cus.getConfirmStatus())) {
						//已到访 到认筹的时候需要
						if (new Integer(1).equals(premises.getRepeatDelayDealTime())) {
							//允许复访顺延
							entity.setOrders(" visited_count desc,create_time ");
						}
					}
					entity.setCustomerPremisesId(cus.getId());
					entity.setSql("new_customer_status = 6");
					entity.setOrders(" t.create_time desc");

					List<FollowUpList> followList = followUpListService.selectListByDto(entity);
					// 到访时间
					Date visitTime = null;
					Boolean visitFlag = true;
					// 认筹时间
					Date payDepositTime = null;
					Boolean payDepositFlag = true;
					// 认购时间
					Date subscribeTime = null;
					Boolean subscribeFlag = true;
					// 签约时间
					Date signTime = null;
					Boolean signFlag = true;
					for (FollowUpList follow : followList) {
						/**
						 * 异常流程: 无效-->待审核、无效-->未到访、无效 --> 到访---一律不执行
						 *
						 * 正常流程： 1,待定(未到访)--》2.到访--》3认筹----》4认购----》签约 跳转流程： 1到访-----》认购 2到访---》签约 3认筹----》签约 0待定-》到访
						 * 1到访-》认筹，2到访-》认购，3到访-》签约 4认筹-》认购，5认筹-》签约 6认购-》签约
						 *
						 */
						if (CustomerStatusEnum.no_valid.getNo().equals(follow.getOldCustomerStatus())
								&& (CustomerStatusEnum.normal.getNo().equals(follow.getNewCustomerStatus())
								|| CustomerStatusEnum.not_visited.getNo().equals(follow.getNewCustomerStatus())
								|| CustomerStatusEnum.has_visited.getNo().equals(follow.getNewCustomerStatus())
						)
						) {
							break;
						}

						// 获取到访时间
						if (visitFlag && CustomerStatusEnum.not_visited.getNo().equals(follow.getOldCustomerStatus())
								&& CustomerStatusEnum.has_visited.getNo().equals(follow.getNewCustomerStatus())) {
							visitTime = follow.getCreateTime();
							visitFlag = false;
						}
						if (visitFlag && follow.getOldCustomerStatus().equals(follow.getNewCustomerStatus())
								&& CustomerStatusEnum.has_visited.getNo().equals(follow.getNewCustomerStatus())) {
							logger.info("复访记录: ", JSONObject.toJSONString(follow));
							visitTime = follow.getCreateTime();
							visitFlag = false;
						}

						// 认筹到签约
						if (payDepositFlag && ConfirmStatusEnum.payDeposit.getNo().equals(follow.getOldConfirmStatus())
								&& ConfirmStatusEnum.sign.getNo().equals(follow.getNewConfirmStatus())) {
							payDepositTime = follow.getCreateTime();
							payDepositFlag = false;
						}
						// 获取认筹时间（到访到认筹）
						if (payDepositFlag && ConfirmStatusEnum.confirm.getNo().equals(follow.getOldConfirmStatus())
								&& ConfirmStatusEnum.payDeposit.getNo().equals(follow.getNewConfirmStatus())) {
							payDepositTime = follow.getCreateTime();
							payDepositFlag = false;
						}

						// 到访到认购
						if (subscribeFlag && ConfirmStatusEnum.subscribe.getNo().equals(follow.getNewConfirmStatus())
								&& CustomerStatusEnum.has_visited.getNo().equals(follow.getNewCustomerStatus())) {
							subscribeTime = follow.getCreateTime();
							subscribeFlag = false;
						}
						// 获取认购时间(认筹到认购)
						if (subscribeFlag && ConfirmStatusEnum.payDeposit.getNo().equals(follow.getOldConfirmStatus())
								&& ConfirmStatusEnum.subscribe.getNo().equals(follow.getNewConfirmStatus())) {
							subscribeTime = follow.getCreateTime();
							subscribeFlag = false;
						}
						// 到访到签约
						if (signFlag && CustomerStatusEnum.has_visited.getNo().equals(follow.getNewCustomerStatus())
								&& ConfirmStatusEnum.sign.getNo().equals(follow.getNewConfirmStatus())) {
							signTime = follow.getCreateTime();
							signFlag = false;
						}
						// 认筹到签约
						if (signFlag && ConfirmStatusEnum.payDeposit.getNo().equals(follow.getOldConfirmStatus())
								&& ConfirmStatusEnum.sign.getNo().equals(follow.getNewConfirmStatus())) {
							signTime = follow.getCreateTime();
							signFlag = false;
						}
						// 获取签约时间(认购到签约)
						if (signFlag && ConfirmStatusEnum.subscribe.getNo().equals(follow.getOldConfirmStatus())
								&& ConfirmStatusEnum.sign.getNo().equals(follow.getNewConfirmStatus())) {
							signTime = follow.getCreateTime();
							signFlag = false;
						}
					}
					// 查询报备楼盘得到流程保护时间
					String saveDay = premises.getSaveDays();
					Calendar currentDate = Calendar.getInstance();
					// 查询报备楼盘是否勾选到访转认筹不再启用保护
					String flag = premises.getCloseProtectMachine();
					// 新版需求增加了单位选项，数据库存的数据单位为分钟
					currentDate.add(Calendar.MINUTE, -Integer.parseInt(saveDay));
					Long currentTime = currentDate.getTime().getTime();
					if (payDepositTime == null && subscribeTime == null && signTime == null) {
						// 到访未认筹
						if (visitTime != null && visitTime.getTime() < currentTime) {
							// 超过流程保护时间（带看保护时间），将报备记录设置为无效
							CustomerPremisesDto customer = new CustomerPremisesDto();
							customer.setId(cus.getId());
							customer.setCustomerStatus(CustomerStatusEnum.no_valid.getNo());
							customer.setDisableType(DisableTypeEnum.protected_invalid.getNo());
							customerPremisesService.update(customer);
							// 往跟进表中插入已过到访保护期记录
							insertFlollowUpList(cus);
							v10BindService.asyncReportInvalidForJob(cus, premises);
							continue;
						}
					}
					if (subscribeTime == null && signTime == null) {
						// 已认筹但未认购
						if (payDepositTime != null && payDepositTime.getTime() < currentTime && "0".equals(flag)) {
							// 超过流程保护时间，将报备记录设置为无效
							CustomerPremisesDto customer = new CustomerPremisesDto();
							customer.setId(cus.getId());
							customer.setCustomerStatus(CustomerStatusEnum.no_valid.getNo());
							customer.setDisableType(DisableTypeEnum.protected_invalid.getNo());
							customerPremisesService.update(customer);
							// 往跟进表中插入已过到访保护期记录
							insertFlollowUpList(cus);
							v10BindService.asyncReportInvalidForJob(cus, premises);
							continue;
						}
					}
					if (signTime == null) {
						// 已认购但未签约
						if (subscribeTime != null && subscribeTime.getTime() < currentTime && "0".equals(flag)) {
							// 超过流程保护时间，将报备记录设置为无效
							CustomerPremisesDto customer = new CustomerPremisesDto();
							customer.setId(cus.getId());
							customer.setCustomerStatus(CustomerStatusEnum.no_valid.getNo());
							customer.setDisableType(DisableTypeEnum.protected_invalid.getNo());
							customerPremisesService.update(customer);
							// 往跟进表中插入已过到访保护期记录
							insertFlollowUpList(cus);
							v10BindService.asyncReportInvalidForJob(cus, premises);
							continue;
						}
					}
				}
			}
			result = 1;
		} catch (Exception e) {
			logger.error("flowConfirm error: {}", e);
		}
		return result;
	}

	@Override
	public int overTradeTimeJob() {
		int result = 0;
		try {
			int pageSize = 300;
			// 查询报备表中所有报备有效的记录(已到访且未签约或交易失败的数据)
			CustomerPremisesDto dto = new CustomerPremisesDto();
			//新版需求开启此job，为了不影响之前的数据，只取发版后的数据
			String dateString = "2019-05-17 00:00:00";
			dto.setCreateTimeBefore(DateUtils.stringToDate(dateString, DateStyle.YYYY_MM_DD_HH_MM_SS.getValue()));
			dto.setCustomerStatus(CustomerStatusEnum.has_visited.getNo());
			dto.setSql(" confirm_status != 3 and confirm_status != 4 ");
			int total = customerPremisesService.overTradeTimeCount(dto);
			logger.info("overTradeTimeJob-->report count: {}", total);
			for (int i = 0; i < (total + pageSize - 1) / 300; i++) {
				List<CustomerPremises> lists = customerPremisesService.selectMyListByDto(dto, pageSize * i, pageSize);
				Set<Long> premisesIdSet = lists.stream().map(CustomerPremises::getPremisesId)
						.collect(Collectors.toSet());
				PremisesDto premisesDto = new PremisesDto();
				premisesDto.setPremisesIds(new ArrayList<>(premisesIdSet));
				List<Premises> premisesList = premisesService.selectSimpleListByDto(premisesDto);
				Map<Long, Premises> premisesMap = premisesList.stream()
						.collect(Collectors.toMap(Premises::getId, Function.identity()));
				for (CustomerPremises cus : lists) {
					Premises premises = premisesMap.get(cus.getPremisesId());
					// 楼盘错误、交易延长未设置或不需要、导入报备不参与
					if (Objects.isNull(premises)
							|| premises.getSaveDaysType() == null
							|| TimeUnitTypeEnum.NONE.getNo().equals(String.valueOf(premises.getSaveDaysType()))
							|| ReportTypeEnum.type_3.getNo().equals(cus.getReportType())) {
						continue;
					}
					// 查询报备楼盘得到流程保护时间
					String saveDay = premises.getSaveDays();
					// 查询报备楼盘是否勾选到访转认筹不再启用保护
					String flag = premises.getCloseProtectMachine();

					String customerStatus = cus.getCustomerStatus();
					String confirmStatus = cus.getConfirmStatus();
					boolean invalidFlag = false;
					if(CustomerStatusEnum.has_visited.getNo().equals(customerStatus)
					&& ConfirmStatusEnum.confirm.getNo().equals(confirmStatus)){
						// 报备记录为已到访未交易
						Date visitTime = cus.getVisitTime();
						Date lastTradeTime = DateUtils.addMinute(visitTime, Integer.valueOf(saveDay));
						if(Objects.nonNull(visitTime)
						&& lastTradeTime.getTime() < System.currentTimeMillis()){
							logger.info("overTradeTimeJob-->reportId: {}, visit time: {}, saveDays: {}", cus.getId(), DateUtils.DateToString(visitTime, DateStyle.YYYY_MM_DD_HH_MM_SS.getValue()), saveDay);
							invalidFlag =true;
						}
					}else if(CustomerStatusEnum.has_visited.getNo().equals(customerStatus)
							&& ConfirmStatusEnum.payDeposit.getNo().equals(confirmStatus)){
						// 报备记录为已到访未交易
						Date payDepositTime = cus.getPayDepositTime();
						Date lastTradeTime = DateUtils.addMinute(payDepositTime, Integer.valueOf(saveDay));
						if(Objects.nonNull(payDepositTime) && "0".equals(flag)
								&& lastTradeTime.getTime() < System.currentTimeMillis()){
							logger.info("overTradeTimeJob-->reportId: {}, payDeposit time: {}, saveDays: {}", cus.getId(), DateUtils.DateToString(payDepositTime, DateStyle.YYYY_MM_DD_HH_MM_SS.getValue()), saveDay);
							invalidFlag =true;
						}
					}else if(CustomerStatusEnum.has_visited.getNo().equals(customerStatus)
							&& ConfirmStatusEnum.subscribe.getNo().equals(confirmStatus)){
						// 报备记录为已到访未交易
						Date subscribeTime = cus.getSubscribeTime();
						Date lastTradeTime = DateUtils.addMinute(subscribeTime, Integer.valueOf(saveDay));
						if(Objects.nonNull(subscribeTime) && "0".equals(flag)
								&& lastTradeTime.getTime() < System.currentTimeMillis()){
							logger.info("overTradeTimeJob-->reportId: {}, subscribe time: {}, saveDays: {}", cus.getId(), DateUtils.DateToString(subscribeTime, DateStyle.YYYY_MM_DD_HH_MM_SS.getValue()), saveDay);
							invalidFlag = true;
						}
					}
					if(invalidFlag){
						// 超过流程保护时间，将报备记录设置为无效
						CustomerPremisesDto customer = new CustomerPremisesDto();
						customer.setId(cus.getId());
						customer.setCustomerStatus(CustomerStatusEnum.no_valid.getNo());
						customer.setDisableType(DisableTypeEnum.protected_invalid.getNo());
						customerPremisesService.update(customer);
						// 往跟进表中插入已过到访保护期记录
						insertFlollowUpList(cus);
						v10BindService.asyncReportInvalidForJob(cus, premises);
						continue;
					}
				}
			}
			result = 1;
		} catch (Exception e) {
			logger.error("overTradeTimeJob error: {}", e);
		}
		return result;
	}

	@Override
	public int setOverVisitTimeForJob() {
		int result = 0;
		// 查询所有的开启超过到访保护时间自动失效的报备，
		// 判断条件1.楼盘：开启逾期到访时间自动失效功能，楼盘销售状态，楼盘上架状态，2.报备：到访审核状态，（报备审核通过且未交易的）
		List<CustomerPremisesDto> list = customerPremisesService.selectCPForVisitJob();
		if (CollectionUtils.isNotEmpty(list)) {
			Set<Long> premisesIds = list.stream().map(CustomerPremisesDto::getPremisesId)
					.collect(Collectors.toSet());
			PremisesDto premisesDto = new PremisesDto();
			premisesDto.setPremisesIds(new ArrayList<>(premisesIds));
			List<Premises> premisesList = premisesService.selectSimpleListByDto(premisesDto);
			Map<Long, Premises> premisesMap = premisesList.stream()
					.collect(Collectors.toMap(Premises::getId, Function.identity()));
			long nowTime = Instant.now().toEpochMilli();
			for (CustomerPremisesDto dto : list) {
				try {
					// 导入报备不参与自动无效
					if (ReportTypeEnum.type_3.getNo().equals(dto.getReportType())) {
						continue;
					}
					Premises premises = premisesMap.get(dto.getPremisesId());
					if (Objects.isNull(premises) || TimeUnitTypeEnum.NONE.getNo().equals(premises.getVisitProtectType())) {
						continue;
					}
					Date hopeVisitTime = dto.getHopeVisitTime();
					if (Objects.isNull(hopeVisitTime)) {
						continue;
					}
					long hvTime = hopeVisitTime.toInstant().toEpochMilli();
					//到访延长时间存储时单位为分钟
					String visitProtect = dto.getVisitProtect();
					long vpTime = Long.valueOf(visitProtect) * 60 * 1000;
					//如果到访延长时间开启的话
					long limitTime = hvTime + vpTime;
					//最终截止时间小于当前时间，把报备客户转为无效客户
					if (limitTime < nowTime) {
						CustomerPremisesDto customerPremisesDto = new CustomerPremisesDto();
						customerPremisesDto.setId(dto.getId());
						customerPremisesDto.setCustomerStatus(CustomerStatusEnum.no_valid.getNo());
						result = customerPremisesService.update(customerPremisesDto);
						if (result > 0) {
							//新增跟进记录
							FollowUpListDto followDto = new FollowUpListDto();
							followDto.setStaffId(dto.getStaffId());
							followDto.setCustomerPremisesId(dto.getId());
							followDto.setOldConfirmStatus(dto.getConfirmStatus());
							followDto.setNewConfirmStatus(dto.getConfirmStatus());
							followDto.setOldCustomerStatus(dto.getCustomerStatus());
							followDto.setNewCustomerStatus(CustomerStatusEnum.no_valid.getNo());
							followDto.setRemark("客户超时未到访，转为无效客户");
							followDto.setFollowType(FollowTypeEnum.CHANNEL.getNo());
							followUpListService.create(followDto);
							v10BindService.asyncReportInvalidForJob(dto, premises);
						}
					}
				} catch (Exception e) {
					logger.error("设置超过报备保护时间job异常：{}, {}", dto.getId(), e);
				}
			}
		}
		result = 1;
		return result;
	}

	@Override
	public int overReportedTimeJob() {
		int result = 0;
		try {
			// 系统当前时间
			Long currentTime = Calendar.getInstance().getTime().getTime();
			CustomerPremisesDto dto = new CustomerPremisesDto();
			dto.setCustomerStatus(CustomerStatusEnum.normal.getNo());
			List<CustomerPremises> lists = customerPremisesService.selectListByDto(dto);
			for (CustomerPremises cus : lists) {
				if (cus.getReportPeriodTime() == null || cus.getLookPeriodTime() == null) {
					continue;
				}
				//报备状态非待审 跳过
				if (!CustomerStatusEnum.normal.getNo().equals(cus.getCustomerStatus())) {
					continue;
				}
				//交易状态非待定 跳过
				if (!ConfirmStatusEnum.confirm.getNo().equals(cus.getConfirmStatus())) {
					continue;
				}
				Long reportTime = cus.getReportPeriodTime().getTime();
				Long lookTime = cus.getLookPeriodTime().getTime();
				int updateRow = 0;
				String remark = "";
				if (lookTime >= reportTime) {
					// 当期望带看时间>报备保护时间,超过报备保护时间,报备设为无效
					if (currentTime > reportTime) {
						CustomerPremisesDto cusDto = new CustomerPremisesDto();
						cusDto.setCustomerStatus(CustomerStatusEnum.no_valid.getNo());
						cusDto.setId(cus.getId());
						cusDto.setUpdateTime(Calendar.getInstance().getTime());
						cusDto.setDisableType(DisableTypeEnum.report_invalid.getNo());
						updateRow = customerPremisesService.newUpdate(cusDto);
						remark = "【已过报备保护时间】 报备无效";
					}
				} else if (lookTime <= reportTime) {
					// 当期望带看时间<报备保护时间,超过期望带看时间,报备设为无效
					if (currentTime > lookTime) {
						CustomerPremisesDto cusDto = new CustomerPremisesDto();
						cusDto.setCustomerStatus(CustomerStatusEnum.no_valid.getNo());
						cusDto.setId(cus.getId());
						cusDto.setUpdateTime(Calendar.getInstance().getTime());
						cusDto.setDisableType(DisableTypeEnum.protected_invalid.getNo());
						updateRow = customerPremisesService.newUpdate(cusDto);
						remark = "【已过期望带看时间】 报备无效";
					}
				}
				if (updateRow > 0) {
					cus.setCustomerStatus(CustomerStatusEnum.no_valid.getNo());
					addFollowForJob(cus, remark);

					//同步至V10
					/*
					 * 同步V10报备审核信息
					 * 判断是否为V10推过来的报备
					 */
					ReportExternalDto reportExternalDto = new ReportExternalDto();
					reportExternalDto.setReportId(cus.getId());
					reportExternalDto.setIsDeleted(DelFlagEnum.UNDEL.getNo());
					List<ReportExternal> reportExternalList = reportExternalService.selectListByDto(reportExternalDto);
					if (org.springframework.util.CollectionUtils.isEmpty(reportExternalList)) {
						continue;
					}

					String uuid = reportExternalList.get(0).getReportUuid();

					if (StringUtils.isEmpty(uuid)) {
						continue;
					}

					//同步报备的审核状态 数据固定的由报备待审到报备无效 可以直接给新旧审核状态直接赋值
					UpdateFirsthandIntentionAuditStatusReqDto v10ReqDto = new UpdateFirsthandIntentionAuditStatusReqDto();
					v10ReqDto.setIntentionUuid(uuid);
					v10ReqDto.setAuditStatus(CustomerStatusEnum.no_valid.getNo());
					v10ReqDto.setOldAuditStatus(CustomerStatusEnum.normal.getNo());
					v10ReqDto.setRemark(remark);

					/*
					 * 同步跟进与附件
					 */
					SyncFollowAndAffixReqDto syncReqDto = new SyncFollowAndAffixReqDto();
					V10IntentionFollowDto followVo = new V10IntentionFollowDto();
					followVo.setIntentionUuid(uuid);
					followVo.setOperationType(OperationTypeEnum.OPERATIONTYPE_3.getCode());
					followVo.setRemark(remark);
					followVo.setOldAuditStatus(CustomerStatusEnum.normal.getNo());
					followVo.setNewAuditStatus(CustomerStatusEnum.no_valid.getNo());
					syncReqDto.setFollowVo(followVo);
					//推送至V10
					v10BindService.updateFirsthandIntentionAuditStatus(v10ReqDto, syncReqDto);

					result += 1;
				}
			}
		} catch (Exception e) {
			logger.error("overReportedTimeJob error: {}", e);
		}
		return result;
	}

	@Override
	public int overReporValidTimeJob() {
		logger.info("报备超时，自动转无效报备！");
		CustomerPremisesDto customerPremisesDto = new CustomerPremisesDto();
		customerPremisesDto.setReportValidTimeAfter(new Date());
		List<String> customerStatusList = new ArrayList<>();
		customerStatusList.add(CustomerStatusEnum.normal.getNo());
		customerStatusList.add(CustomerStatusEnum.not_visited.getNo());
		customerPremisesDto.setCustomerStatusList(customerStatusList);
		List<CustomerPremises> cusPreList = customerPremisesService.selectListByDto(customerPremisesDto);
		logger.info("overReporValidTimeJob  ---> 成功查询cusPreList：{}",JSONObject.toJSONString(cusPreList));
		List<CustomerPremises> toUpdateList = Lists.newArrayList();
		int count = 0;
		if(CollectionUtils.isNotEmpty(cusPreList)){
			for(int ii=0; ii<cusPreList.size(); ii++){
				CustomerPremises cusPre = cusPreList.get(ii);
				if(Objects.isNull(cusPre) || Objects.isNull(cusPre.getReportValidTime())){
					continue;
				}
				toUpdateList.add(cusPre);
				count++;
				if(toUpdateList.size() >= 1000){
					setReportToInvalid(toUpdateList);
					toUpdateList.clear();
				}
			}
			setReportToInvalid(toUpdateList);
		}

		return count;
	}

	@Override
	public int sendM2Again() {
		List<ApiFailLog> list = apiFailLogDao.listApiFailLogBySendM2Again();
		if (CollectionUtils.isNotEmpty(list)){
			int successCount = 0;
			logger.info("sendM2Again ------------------ list count :" + list.size());
			for (ApiFailLog apiFailLog : list){
				int count = reportCommonService.customerToM2Again(apiFailLog);
				successCount = successCount + count;
			}
			logger.info("sendM2Again 重新推送成功数量 count :" + successCount);
		}
		return 1;
	}

	void setReportToInvalid(List<CustomerPremises> customerPremisesList){
		logger.info("setReportToInvalid   入参customerPremisesList：{}",JSONObject.toJSONString(customerPremisesList));
		List<String> cusPreIds = customerPremisesList.stream().map(item -> String.valueOf(item.getId())).collect(Collectors.toList());
		logger.info("setReportToInvalid   超时报备{}",JSONObject.toJSONString(cusPreIds));
		CustomerPremisesDto customerPremisesDto = new CustomerPremisesDto();
		customerPremisesDto.setCustomerIds(cusPreIds);
		customerPremisesDto.setCustomerStatus(CustomerStatusEnum.no_valid.getNo());
		customerPremisesDto.setDisableType(DisableTypeEnum.over_report_valid_time.getNo());
		customerPremisesService.updateByIds(customerPremisesDto);

		customerPremisesList.forEach(item -> {
			FollowUpListDto followUpListDto = new FollowUpListDto();
			followUpListDto.setCustomerPremisesId(item.getId());
			followUpListDto.setStaffId(item.getStaffId());
			followUpListDto.setOldCustomerStatus(item.getCustomerStatus());
			followUpListDto.setNewCustomerStatus(CustomerStatusEnum.no_valid.getNo());
			followUpListDto.setOldConfirmStatus(item.getConfirmStatus());
			followUpListDto.setNewConfirmStatus(item.getConfirmStatus());
			followUpListDto.setOldCommissionStatus(item.getCommissionStatus());
			followUpListDto.setNewCommissionStatus(item.getCommissionStatus());
			followUpListDto.setFollowType(FollowTypeEnum.CHANNEL.getNo());
			followUpListDto.setRemark("超过报备有效期，转为无效报备");
			followUpListService.create(followUpListDto);
			logger.info("setReportToInvalid 报备超时添加跟进信息followUpListDto：{}",JSONObject.toJSONString(followUpListDto));

			/**
			 * 同步至V10
			 * 同步V10报备审核信息
			 * 判断是否为V10推过来的报备
			 */
			logger.info("报备超时，自动转无效报备，同步v10");
			ReportExternalDto reportExternalDto = new ReportExternalDto();
			reportExternalDto.setReportId(item.getId());
			reportExternalDto.setIsDeleted(DelFlagEnum.UNDEL.getNo());
			List<ReportExternal> reportExternalList = reportExternalService.selectListByDto(reportExternalDto);
			logger.info("setReportToInvalid  报备外部关联关系reportExternalList：{}",JSONObject.toJSONString(reportExternalList));
			if (!CollectionUtils.isEmpty(reportExternalList)) {
				String uuid = reportExternalList.get(0).getReportUuid();
				logger.info("setReportToInvalid  报备超时推送至v10，报备{}",reportExternalList.get(0));

				if (!StringUtils.isEmpty(uuid)) {
					logger.info("超过报备有效期，同步v10，intentionUuid：{}",uuid);
					UpdateFirsthandIntentionAuditStatusReqDto v10ReqDto = new UpdateFirsthandIntentionAuditStatusReqDto();
					v10ReqDto.setIntentionUuid(uuid);
					v10ReqDto.setAuditStatus(CustomerStatusEnum.no_valid.getNo());
					v10ReqDto.setOldAuditStatus(CustomerStatusEnum.normal.getNo());
					v10ReqDto.setRemark("超过报备有效期，转为无效报备");

					/**
					 * 同步跟进与附件
					 */
					SyncFollowAndAffixReqDto syncReqDto = new SyncFollowAndAffixReqDto();
					V10IntentionFollowDto followVo = new V10IntentionFollowDto();
					followVo.setIntentionUuid(uuid);
					followVo.setOperationType(OperationTypeEnum.OPERATIONTYPE_3.getCode());
					followVo.setRemark("超过报备有效期，转为无效报备");
					followVo.setOldAuditStatus(CustomerStatusEnum.normal.getNo());
					followVo.setNewAuditStatus(CustomerStatusEnum.no_valid.getNo());
					syncReqDto.setFollowVo(followVo);
					//推送至V10
					logger.info("setReportToInvalid 推送至V10,v10ReqDto:{},syncReqDto:{}",JSONObject.toJSONString(v10ReqDto),JSONObject.toJSONString(syncReqDto));
					v10BindService.updateFirsthandIntentionAuditStatus(v10ReqDto, syncReqDto);
					logger.info("setReportToInvalid 报备超时推送v10成功！");
				}
			}
		});
	}

	// 向跟进表中记录因已过到访保护期时间无效
	private void insertFlollowUpList(CustomerPremises cus) {
		// 往跟进表中插入已过到访保护期记录
		FollowUpListDto fulDto2 = new FollowUpListDto();
		fulDto2.setCustomerPremisesId(cus.getId());
		fulDto2.setOrders("create_time desc");
		List<FollowUpList> list = followUpListService.selectListByDto(fulDto2);
		FollowUpList newFollow = list.get(0);
		FollowUpListDto fulDto = new FollowUpListDto();
		fulDto.setCustomerPremisesId(cus.getId());
		fulDto.setStaffId(cus.getStaffId());
		fulDto.setOldConfirmStatus(newFollow.getNewConfirmStatus());
		fulDto.setNewConfirmStatus(newFollow.getNewConfirmStatus());
		fulDto.setOldCustomerStatus(newFollow.getNewCustomerStatus());
		fulDto.setNewCustomerStatus(CustomerStatusEnum.no_valid.getNo());
		fulDto.setOldCommissionStatus(newFollow.getNewCommissionStatus());
		fulDto.setNewCommissionStatus(newFollow.getNewCommissionStatus());
		fulDto.setFollowType(FollowTypeEnum.CHANNEL.getNo());
		fulDto.setRemark("客户超时未交易，转为无效客户");
		followUpListService.create(fulDto);
	}


	/**
	 * 设置为无效之后添加跟进
	 *
	 * @param customerPremises
	 * @param remark
	 */
	public void addFollowForJob(CustomerPremises customerPremises, String remark) {
		// 往跟进表中插入已过到访保护期记录
		FollowUpListDto fulDto2 = new FollowUpListDto();
		fulDto2.setCustomerPremisesId(customerPremises.getId());
		fulDto2.setOrders("create_time desc");
		List<FollowUpList> list = followUpListService.selectListByDto(fulDto2);
		FollowUpList newFollow = list.get(0);
		FollowUpListDto fulDto = new FollowUpListDto();
		fulDto.setCustomerPremisesId(customerPremises.getId());
		fulDto.setStaffId(customerPremises.getStaffId());
		fulDto.setOldConfirmStatus(newFollow.getNewConfirmStatus());
		fulDto.setNewConfirmStatus(customerPremises.getConfirmStatus());
		fulDto.setOldCustomerStatus(newFollow.getNewCustomerStatus());
		fulDto.setNewCustomerStatus(customerPremises.getCustomerStatus());
		fulDto.setOldCommissionStatus(newFollow.getNewCommissionStatus());
		fulDto.setNewCommissionStatus(customerPremises.getCommissionStatus());
		fulDto.setFollowType(FollowTypeEnum.CHANNEL.getNo());
		fulDto.setRemark(remark);
		if (("【已过报备保护时间】 报备无效").equals(remark) || ("【已过期望带看时间】 报备无效").equals(remark)) {
			fulDto.setFollowUpType(FollowUpEnum.decision_invalid.getNo());
		}
		followUpListService.create(fulDto);
	}
}
